package server

import (
	"container/list"
	"fmt"
	"server5/Interface"
	"server5/protobuf"
	"server5/utils"
	"strings"
	"sync"
)

type GameLobby struct {
	OnlineUsers map[string]Interface.IUser
	OnlineLock sync.RWMutex

	ReadyUsers *list.List
	ReadyLock sync.RWMutex
}

var gameLobby *GameLobby

func GetGameLobby() *GameLobby {
	if gameLobby == nil {
		gameLobby = &GameLobby{
			OnlineUsers: make(map[string]Interface.IUser,utils.GlobalObject.MaxConn),
			ReadyUsers: list.New(),
		}
	}
	return gameLobby
}

func (g *GameLobby) AddOnlineUser(userName string,user Interface.IUser) bool {
	g.OnlineLock.Lock()
	defer g.OnlineLock.Unlock()

	if g.OnlineUsers[userName] == nil {
		g.OnlineUsers[userName] = user
		return true
	}
	return false
}

func (g *GameLobby) RemoveOnlineUser(userName string) {
	g.OnlineLock.Lock()
	defer g.OnlineLock.Unlock()

	delete(g.OnlineUsers,userName)
}

func (g *GameLobby) GetAllOnlineUserName() (usersName string){
	g.OnlineLock.RLock()
	defer g.OnlineLock.RUnlock()

	for i,_ := range g.OnlineUsers {
		usersName += i + " "
	}
	return strings.TrimSpace(usersName)
}


func (g *GameLobby) AddReadyUser(userName string){
	g.ReadyLock.Lock()
	defer g.ReadyLock.Unlock()

	g.ReadyUsers.PushBack(g.OnlineUsers[userName])
	g.OnlineUsers[userName].SetStatus(utils.Ready)

	if g.ReadyUsers.Len() >= 4 {
		c1 := g.ReadyUsers.Remove(g.ReadyUsers.Front()).(Interface.IUser)
		c2 := g.ReadyUsers.Remove(g.ReadyUsers.Front()).(Interface.IUser)
		c3 := g.ReadyUsers.Remove(g.ReadyUsers.Front()).(Interface.IUser)
		c4 := g.ReadyUsers.Remove(g.ReadyUsers.Front()).(Interface.IUser)
		go NewGameRoom(c1,c2,c3,c4).StartGame()
	}
	//Debug
	fmt.Println("当前准备就绪的玩家：")
	for e := g.ReadyUsers.Front(); e != nil; e = e.Next() {
		fmt.Println(e.Value.(Interface.IUser).UserInfo())
	}
}

func (g *GameLobby) RemoveReadyUser(userName string){
	g.ReadyLock.Lock()
	defer g.ReadyLock.Unlock()

	for e := g.ReadyUsers.Front(); e != nil; e = e.Next() {
		if e.Value.(Interface.IUser).UserInfo().UserName == userName{
			g.ReadyUsers.Remove(e)
			//Debug
			fmt.Println("移除准备玩家成功")
			return
		}
	}
}


func (g *GameLobby) UpdateOnlineUsers(){

	fmt.Println("开始更新在线玩家信息")

	var updateOnlineUsersMsg protobuf.UpdateOnlineUsersMsg
	updateOnlineUsersMsg.UsersList = g.GetAllOnlineUserName()

	fmt.Println("当前在线玩家: ",updateOnlineUsersMsg.UsersList)

	for i,v := range g.OnlineUsers{
		v.Connection().SendMsg(protobuf.MsgType_UpdateOnlineUsers,&updateOnlineUsersMsg)
		fmt.Println( i, "更新在线玩家信息成功")
	}

	fmt.Println("更新在线玩家信息完成")
	return
}

func (g *GameLobby) OffLine(userName string){

	//Debug
	fmt.Println(userName,"玩家下线")

	g.RemoveReadyUser(userName)
	g.RemoveOnlineUser(userName)
	g.UpdateOnlineUsers()
}


